package com.ruoyi.waterDistribution.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.core.constant.BusinessConstants;
import com.ruoyi.common.core.domain.base.datam.StCrossB;
import com.ruoyi.common.core.domain.base.datam.WcChanB;
import com.ruoyi.common.core.domain.business.waterDistribution.WiGetvolM;
import com.ruoyi.common.core.domain.business.waterDistribution.WiOrgplanM;
import com.ruoyi.common.core.domain.business.waterDistribution.WiPeriodY;
import com.ruoyi.common.core.domain.business.waterManagement.WrStatvolM;
import com.ruoyi.common.core.enums.TenEnum;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.business.BusinessUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.waterDistribution.controller.WiGetvolMController;
import com.ruoyi.waterDistribution.mapper.WiGetvolMMapper;
import com.ruoyi.waterDistribution.mapper.WiPeriodYMapper;
import com.ruoyi.waterDistribution.service.IWiGetvolMService;
import com.ruoyi.waterDistribution.vo.WiLandBVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 取水断面月度调水水量计算Service业务层处理
 *
 * @author ps
 * @date 2023-02-16
 */
@Service
public class WiGetvolMServiceImpl implements IWiGetvolMService {
    private static final Logger log = LoggerFactory.getLogger(WiGetvolMServiceImpl.class);

    @Autowired
    private WiGetvolMMapper wiGetvolMMapper;
    @Autowired
    private WiPeriodYMapper wiPeriodYMapper;

    /**
     * 查询取水断面月度调水水量计算
     *
     * @param crossCd 取水断面月度调水水量计算主键
     * @return 取水断面月度调水水量计算
     */
    @Override
    public WiGetvolM selectWiGetvolMByCrossCd(String crossCd) {
        return wiGetvolMMapper.selectWiGetvolMByCrossCd(crossCd);
    }

    /**
     * 查询取水断面月度调水水量计算列表
     *
     * @param wiGetvolM 取水断面月度调水水量计算
     * @return 取水断面月度调水水量计算
     */
    @Override
    public List<WiGetvolM> selectWiGetvolMList(WiGetvolM wiGetvolM) {
        return wiGetvolMMapper.selectWiGetvolMList(wiGetvolM);
    }

    /**
     * 新增取水断面月度调水水量计算
     *
     * @param wiGetvolM 取水断面月度调水水量计算
     * @return 结果
     */
    @Override
    public int insertWiGetvolM(WiGetvolM wiGetvolM) {
        return wiGetvolMMapper.insertWiGetvolM(wiGetvolM);
    }

    /**
     * 修改取水断面月度调水水量计算
     *
     * @param wiGetvolM 取水断面月度调水水量计算
     * @return 结果
     */
    @Override
    public int updateWiGetvolM(WiGetvolM wiGetvolM) {
        return wiGetvolMMapper.updateWiGetvolM(wiGetvolM);
    }

    /**
     * 批量删除取水断面月度调水水量计算
     *
     * @param crossCd 需要删除的取水断面月度调水水量计算主键
     * @return 结果
     */
    @Override
    public int deleteWiGetvolMByCrossCds(String crossCd, String getYm) {
        return wiGetvolMMapper.deleteWiGetvolMByCrossCds(crossCd, getYm);
    }

    /**
     * 删除取水断面月度调水水量计算信息
     *
     * @param crossCd 取水断面月度调水水量计算主键
     * @return 结果
     */
    @Override
    public int deleteWiGetvolMByCrossCd(String crossCd,String getYm) {
        return wiGetvolMMapper.deleteWiGetvolMByCrossCd(crossCd,getYm);
    }

    /**
     * 调水过程核定
     *
     * @param year
     * @param crossCd
     */
    @Override
    public int setCroVol(String year, String crossCd) throws Exception {

        /**返回数据定义 start*/
        ArrayList<HashMap<String, Object>> resList = new ArrayList<>();
        BigDecimal ten1;//上旬水量
        BigDecimal ten2;//中旬水量
        BigDecimal ten3;//下旬水量
        BigDecimal monthSum;//月水量
        /**返回数据定义 new*/
        //获取渠系利用系数 start
        StCrossB stCrossB = wiGetvolMMapper.getCrossInfo(crossCd);
        if (stCrossB == null) {
            return 0;
        }
        WcChanB wcChanB = wiGetvolMMapper.getChanInfo(stCrossB.getChanCd());
        BigDecimal chanRate = wcChanB.getChanRate() == null ? new BigDecimal("1") : wcChanB.getChanRate();
        log.info("渠系利用系数 ：" + chanRate);
        //获取渠系利用系数 end

        //将渠系编码转换 start
        String chanCdQuery;
        HashMap<String, Object> chanCodeInfo = BusinessUtils.getChanCodeInfo(wcChanB.getChanCd());
        chanCdQuery = chanCodeInfo.get("resCode") + "";
        //将渠系编码转换 end

        //获取地块
        List<WiLandBVo> wiLandBVoList = wiGetvolMMapper.getLandByChanCd(chanCdQuery);
//        List<WiLandBVo> wiLandBVoList = wiGetvolMMapper.getLandByCrossCd(crossCd);
        //按断面分组统计地块面积
        Map<String, Double> wiLandBVoMap = wiLandBVoList.parallelStream().collect(Collectors.groupingBy(WiLandBVo::getCrossCd,
                Collectors.summingDouble(s -> Double.parseDouble(s.getLandSize() + ""))));
        //12个月
        for (String monthStr : BusinessConstants.MONTHS) {
            //每月变量清零
            ten1 = new BigDecimal("0");//上旬水量
            ten2 = new BigDecimal("0");//中旬水量
            ten3 = new BigDecimal("0");//下旬水量
            monthSum = new BigDecimal("0");//月水量
            //遍历断面，过滤出每个断面的地块后 再根据作物分组 然后结合渠系利用系数计算定额水量
            for (Map.Entry<String, Double> entry : wiLandBVoMap.entrySet()) {
                log.info(">>>>>>>>> " + entry.getKey() + "=" + entry.getValue());
                //过滤出每个断面的地块后
                List<WiLandBVo> wiLandBVoByCrossCdList = wiLandBVoList.stream().filter(vo -> entry.getKey().equals(vo.getCrossCd())).collect(Collectors.toList());
                //根据作物分组求地块面积和
                Map<String, Double> landSizeSumByCropCdMap = wiLandBVoByCrossCdList.parallelStream().collect(Collectors.groupingBy(WiLandBVo::getCropCd,
                        Collectors.summingDouble(s -> Double.parseDouble(s.getLandSize() + ""))));


                for (Map.Entry<String, Double> landSizeSumByCropCdEntry : landSizeSumByCropCdMap.entrySet()) {
                    log.info("作物分组求地块面积和>>>>>>>>> " + entry.getKey() + "=" + landSizeSumByCropCdEntry.getKey() + "=" + landSizeSumByCropCdEntry.getValue());
                    //根据年度和作物查询周期定额 start
                    List<WiPeriodY> wiPeriodYList = wiPeriodYMapper.selectWiPeriodListbyCropAndCropCd(year, landSizeSumByCropCdEntry.getKey());
                    //根据年度和作物查询周期定额 end
                    //遍历周期定额
                    for (WiPeriodY wiPeriodY : wiPeriodYList) {
                        //遍历上中下旬
                        for (HashMap<String, String> tensMap : BusinessConstants.TENSLIST) {
                            BigDecimal periodVol = wiPeriodY.getPeriodVol() == null ? new BigDecimal("0") : wiPeriodY.getPeriodVol();
                            String beginDate = DateUtils.dateTime(wiPeriodY.getBeginDate());
                            String endDate = DateUtils.dateTime(wiPeriodY.getEndDate());
                            String beginDate2 = year + "-" + monthStr + "-" + tensMap.get("tenStart");
                            String endDate2 = year + "-" + monthStr + "-" + tensMap.get("tenEnd");
                            //动态调整当月最后一天
                            if (tensMap.get("tenEnd").equals("31")) {
                                endDate2 = BusinessUtils.getMonthLastday(year, monthStr);
                            }
                            //定额包含天数
                            int i = BusinessUtils.differentDaysByMillisecond(wiPeriodY.getBeginDate(), wiPeriodY.getEndDate());
                            //旬占定额天数中的几天
                            int days = BusinessUtils.getDays(beginDate, endDate, beginDate2, endDate2);
                            //上旬
                            if (TenEnum.TEN1.getCode().equals(tensMap.get("ten1"))) {
                                ten1 = ten1.add(new BigDecimal(entry.getValue()).multiply(periodVol.multiply(new BigDecimal(days).divide(new BigDecimal(i), 2, BigDecimal.ROUND_DOWN)).setScale(2)));
                                ten1 = ten1.divide(new BigDecimal(chanRate + ""));
                            }
                            //中旬
                            if (TenEnum.TEN2.getCode().equals(tensMap.get("ten2"))) {
                                ten2 = ten2.add(new BigDecimal(entry.getValue()).multiply(periodVol.multiply(new BigDecimal(days).divide(new BigDecimal(i), 2, BigDecimal.ROUND_DOWN)).setScale(2)));
                                ten2 = ten2.divide(new BigDecimal(chanRate + ""));
                            }
                            //下旬
                            if (TenEnum.TEN3.getCode().equals(tensMap.get("ten3"))) {
                                ten3 = ten3.add(new BigDecimal(entry.getValue()).multiply(periodVol.multiply(new BigDecimal(days).divide(new BigDecimal(i), 2, BigDecimal.ROUND_DOWN)).setScale(2)));
                                ten3 = ten3.divide(new BigDecimal(chanRate + ""));
                            }
                            monthSum = monthSum.add(new BigDecimal(entry.getValue()).multiply(periodVol.multiply(new BigDecimal(days).divide(new BigDecimal(i), 2, BigDecimal.ROUND_DOWN)).setScale(2)));
                            monthSum = monthSum.divide(new BigDecimal(chanRate + ""));
                        }
                    }
                }

            }
            int i = insertWiGetvolM(crossCd, year, monthStr, ten1, ten2, ten3, monthSum);
            if (i != 1) {
                throw new RuntimeException("汇总用水计划失败，请联系管理员~001");
            }
        }
        return 1;
    }

    /**
     * 汇总年度各个入境渠道取水断面的旬水量
     *
     * @param year
     * @param chanCd
     */
    @Override
    public ArrayList<Object> caleCroVol(String year, String chanCd) {
        String chanCdQuery;
        HashMap<String, Object> addvAndOrgCodeInfo = BusinessUtils.getChanCodeInfo(chanCd);
        chanCdQuery = addvAndOrgCodeInfo.get("resCode") + "";
        List<WiGetvolM> wiGetvolMByGetYmAndChanCdList = wiGetvolMMapper.getWiGetvolMByGetYmAndChanCd(year, chanCdQuery);
        //将计划按planYm分组把计划用水求和
        Map<String, Double> MonthSumCollect = wiGetvolMByGetYmAndChanCdList.parallelStream().collect(Collectors.groupingBy(WiGetvolM::getGetYm,
                Collectors.summingDouble(s -> Double.parseDouble(s.getMonGet() + ""))));
        //上旬计划和
        Map<String, Double> ten1Collect = wiGetvolMByGetYmAndChanCdList.parallelStream().collect(Collectors.groupingBy(WiGetvolM::getGetYm,
                Collectors.summingDouble(s -> Double.parseDouble(s.getFirstGet() + ""))));
        //中旬计划和
        Map<String, Double> ten2Collect = wiGetvolMByGetYmAndChanCdList.parallelStream().collect(Collectors.groupingBy(WiGetvolM::getGetYm,
                Collectors.summingDouble(s -> Double.parseDouble(s.getSecondGet() + ""))));
        //下旬计划和
        Map<String, Double> ten3Collect = wiGetvolMByGetYmAndChanCdList.parallelStream().collect(Collectors.groupingBy(WiGetvolM::getGetYm,
                Collectors.summingDouble(s -> Double.parseDouble(s.getThirdGet() + ""))));
        //整理页面数据格式 start
        ArrayList<Object> res = new ArrayList<>();
        for (String monthStr : BusinessConstants.MONTHS) {
            if (monthStr.equals("01")) {
                continue;
            }
            //上中下旬
            for (HashMap<String, String> tensMap : BusinessConstants.TENSLIST) {
                ArrayList<String> planInfo = new ArrayList<>();
                planInfo.add(year);
                if (monthStr.equals("02") || monthStr.equals("03") || monthStr.equals("04")) {
                    planInfo.add("春灌");
                }
                if (monthStr.equals("05") || monthStr.equals("06") || monthStr.equals("07") || monthStr.equals("08")) {
                    planInfo.add("夏灌");
                }
                if (monthStr.equals("09") || monthStr.equals("10") || monthStr.equals("11") || monthStr.equals("12")) {
                    planInfo.add("冬灌");
                }
                planInfo.add(Integer.parseInt(monthStr) + "月");
                if ("ten1".equals(tensMap.get("ten1"))) {
                    planInfo.add("上旬");
                    planInfo.add(ten1Collect.get(year + monthStr) + "");
                }
                if ("ten2".equals(tensMap.get("ten2"))) {
                    planInfo.add("中旬");
                    planInfo.add(ten2Collect.get(year + monthStr) + "");
                }
                if ("ten3".equals(tensMap.get("ten3"))) {
                    planInfo.add("下旬");
                    planInfo.add(ten3Collect.get(year + monthStr) + "");
                }
                res.add(planInfo);
            }
            ArrayList<String> planInfo = new ArrayList<>();
            planInfo.add(year);
            if (monthStr.equals("02") || monthStr.equals("03") || monthStr.equals("04")) {
                planInfo.add("春灌");
            }
            if (monthStr.equals("05") || monthStr.equals("06") || monthStr.equals("07") || monthStr.equals("08")) {
                planInfo.add("夏灌");
            }
            if (monthStr.equals("09") || monthStr.equals("10") || monthStr.equals("11") || monthStr.equals("12")) {
                planInfo.add("冬灌");
            }
            planInfo.add(Integer.parseInt(monthStr) + "月");
            planInfo.add("月总量");
            planInfo.add(MonthSumCollect.get(year + monthStr) + "");
            res.add(planInfo);
        }
        return res;

        //整理页面数据格式 end
    }

    /**
     * 年度配水计划
     *
     * @param year
     * @param chanCd
     * @return
     */
    @Override
    public ArrayList<Object> getCroVolYear(String year, String chanCd) {
        ArrayList<Object> res = new ArrayList<>();
        String chanCdQuery;
        HashMap<String, Object> chanCodeInfo = BusinessUtils.getChanCodeInfo(chanCd);
        chanCdQuery = chanCodeInfo.get("resCode") + "";
        //查询 月计划总和
        List<WiGetvolM> croVolYearList = wiGetvolMMapper.getCroVolYear(year, chanCdQuery);
        //按断面编码分组出年用水计划
        Map<String, Double> yearSumCollect = croVolYearList.parallelStream().collect(Collectors.groupingBy(WiGetvolM::getCrossCd,
                Collectors.summingDouble(s -> Double.parseDouble(s.getMonGet() == null ? "0" : s.getMonGet() + ""))));
        for (Map.Entry<String, Double> entry : yearSumCollect.entrySet()) {
            if (chanCd.equals(entry.getKey())) {
                continue;
            }
            HashMap<String, Object> monthVolMap = new HashMap<>();
            monthVolMap.put("crossCd", entry.getKey());

            //查询断面名称 start
            String orgNm = wiGetvolMMapper.getCrossNm(entry.getKey());
            monthVolMap.put("crossNm", orgNm);
            //查询断面名称 end

            //过滤出断面当年计划
            List<WiGetvolM> collect = croVolYearList.stream().filter(vo -> vo.getCrossCd().equals(entry.getKey())).filter(vo -> vo.getGetYm().substring(0, 4).equals(year)).collect(Collectors.toList());
            for (WiGetvolM wiGetvolM : collect) {
                for (String monthStr : BusinessConstants.MONTHS) {
                    if ((year + monthStr).equals(wiGetvolM.getGetYm())) {
                        monthVolMap.put("month" + monthStr, wiGetvolM.getMonGet());
                        monthVolMap.put("month" + monthStr + "-ten1", wiGetvolM.getFirstGet());
                        monthVolMap.put("month" + monthStr + "-ten2", wiGetvolM.getSecondGet());
                        monthVolMap.put("month" + monthStr + "-ten3", wiGetvolM.getThirdGet());
                    }
                }
            }
            monthVolMap.put("sum", entry.getValue());
            res.add(monthVolMap);
        }
        return res;
    }

    /**
     * 年度调水分析 -- 显示入境取水断面的配水量和实测水量的对比
     *
     * @param year
     * @param chanCd
     */
    @Override
    public HashMap<String, Object> croVolAnalys(String year, String chanCd) {
        HashMap<String, Object> res = new HashMap<>();
        String chanCdQuery;
        HashMap<String, Object> chanCodeInfo = BusinessUtils.getChanCodeInfo(chanCd);
        chanCdQuery = chanCodeInfo.get("resCode") + "";
        TreeMap<String, Object> monthVolMap = new TreeMap<>();
        //查询 月计划总和
        List<WiGetvolM> croVolYearList = wiGetvolMMapper.getCroVolYear(year, chanCdQuery);
        //12个月的月配水量
        for (String monthStr : BusinessConstants.MONTHS) {
            BigDecimal monSumCroVol = new BigDecimal("0");
            for (WiGetvolM wiGetvolM : croVolYearList) {
                if ((year + monthStr).equals(wiGetvolM.getGetYm())) {
                    monSumCroVol = monSumCroVol.add(wiGetvolM.getMonGet());
                }
                monthVolMap.put("month" + monthStr, monSumCroVol);
            }
        }
        List<Object> monthVolList = new ArrayList<>(monthVolMap.values());
        res.put("plan", monthVolList);

        //查询实际用水 start
        TreeMap<String, Object> accVolMap = new TreeMap<>();
        //根据断面查测站 测站月水量数据
        List<WrStatvolM> wrStatvolMList = wiGetvolMMapper.getWrStatvolMByYearAndChanCd(year, chanCdQuery);
        //12个月的月实际水量
        for (String monthStr : BusinessConstants.MONTHS) {
            BigDecimal monSumCroVol = new BigDecimal("0");
            for (WrStatvolM wrStatvolM : wrStatvolMList) {
                if ((year + monthStr).equals(wrStatvolM.getStatMon())) {
                    monSumCroVol = monSumCroVol.add(wrStatvolM.getMonVol().multiply(new BigDecimal("10000")));
                }
                accVolMap.put("month" + monthStr, monSumCroVol);
            }
        }
        List<Object> accVolList = new ArrayList<>(accVolMap.values());
        res.put("acc", accVolList);
        //查询实际用水 end
        return res;
    }

    /**
     * 导入上一年调水数据
     * @param year
     * @param crossCd
     * @return
     */
    @Override
    public List<WiGetvolM> importLastYearData(String year, String crossCd) {
        WiGetvolM wiGetvolM = new WiGetvolM();
        wiGetvolM.setGetYm(year);
        wiGetvolM.setCrossCd(crossCd);
        List<WiGetvolM> wiGetvolMS = wiGetvolMMapper.selectWiGetvolMList(wiGetvolM);
        if (wiGetvolMS.size() == 0) {
            return wiGetvolMS;
        } else {
            for (WiGetvolM vo : wiGetvolMS) {
                wiGetvolMMapper.deleteWiGetvolMByCrossCd(crossCd, (Integer.parseInt(year) + 1) + vo.getGetYm().substring(4, 6));
                WiGetvolM wiGetvolM2 = new WiGetvolM();
                wiGetvolM2.setCrossCd(crossCd);
                wiGetvolM2.setGetYm((Integer.parseInt(year) + 1) + vo.getGetYm().substring(4, 6));

                wiGetvolM2.setFirstGet(vo.getFirstGet());
                wiGetvolM2.setFirstCtrl(vo.getFirstCtrl());
                wiGetvolM2.setSecondGet(vo.getSecondGet());
                wiGetvolM2.setSecondCtrl(vo.getSecondCtrl());
                wiGetvolM2.setThirdGet(vo.getThirdGet());
                wiGetvolM2.setThirdCtrl(vo.getThirdCtrl());
                wiGetvolM2.setMonGet(vo.getMonGet());
                wiGetvolM2.setMonCtrl(vo.getMonCtrl());
                //操作人相关信息
                wiGetvolM2.setOperDate(new Date());
                wiGetvolM2.setLastId(SecurityUtils.getUserId() + "");
                wiGetvolMMapper.insertWiGetvolM(wiGetvolM2);

            }
            WiGetvolM wiGetvolM0 = new WiGetvolM();
            wiGetvolM0.setGetYm((Integer.parseInt(year) + 1)+"");
            wiGetvolM0.setCrossCd(crossCd);
            return wiGetvolMMapper.selectWiGetvolMList(wiGetvolM0);
        }
    }

    private int insertWiGetvolM(String crossCd, String year, String monthStr, BigDecimal ten1, BigDecimal ten2, BigDecimal ten3, BigDecimal monthSum) {
        WiGetvolM wiGetvolM = new WiGetvolM();
        wiGetvolM.setCrossCd(crossCd);
        wiGetvolM.setGetYm(year + monthStr);
        //判断是否已经存在计划，若存在则删除后重新添加汇总数据
        List<WiGetvolM> wiGetvolMs = wiGetvolMMapper.selectWiGetvolMList(wiGetvolM);
        if (wiGetvolMs.size() > 0) {
            wiGetvolMMapper.deleteWiGetvolMByCrossCds(crossCd, year + monthStr);
        }
        wiGetvolM.setFirstGet(ten1);
        wiGetvolM.setFirstCtrl(ten1);
        wiGetvolM.setSecondGet(ten2);
        wiGetvolM.setSecondCtrl(ten2);
        wiGetvolM.setThirdGet(ten3);
        wiGetvolM.setThirdCtrl(ten3);
        wiGetvolM.setMonGet(monthSum);
        wiGetvolM.setMonCtrl(monthSum);
        //操作人相关信息
        wiGetvolM.setOperDate(new Date());
        wiGetvolM.setLastId(SecurityUtils.getUserId() + "");

        return wiGetvolMMapper.insertWiGetvolM(wiGetvolM);
    }
}
